package cn.okcode.api.framework.interceptor;

import cn.hutool.core.util.ClassUtil;
import cn.okcode.api.framework.ActionContext;
import cn.okcode.api.framework.ActionInterceptor;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * 拦截器处理器
 *
 * @author pyk13
 */
public class InterceptorHandler {
    private static final Logger logger = LogManager.getLogger(InterceptorHandler.class.getName());

    private static List<ActionInterceptor> interceptorChain;
    private static final String basePackageName = InterceptorHandler.class.getPackage().getName();

    public static InterceptorHandler defaultHandler = new InterceptorHandler();

    private InterceptorHandler() {
        initialize();
    }

    private void initialize() {
        if (interceptorChain == null) {
            interceptorChain = new ArrayList<>();
            Set<Class<?>> classes = ClassUtil.scanPackageBySuper(basePackageName, ActionInterceptor.class);
            for (Class<?> clazz : classes) {
                try {
                    ActionInterceptor interceptor = (ActionInterceptor) clazz.newInstance();
                    interceptorChain.add(interceptor);
                    logger.error("初始化拦截器：" + clazz.getName());
                } catch (InstantiationException | IllegalAccessException e) {
                    logger.error("创建拦截器出错", e);
                }
            }
        }
    }

    public void beforeInvoke(ActionContext context) {
        Objects.requireNonNull(context.getCallee());
        for (ActionInterceptor interceptor : interceptorChain) {
            try {
                interceptor.beforeInvoke(context);
            } catch (Exception e) {
                Logger logger = LogManager.getLogger(context.getCallee().getClazzName());
                logger.error("执行beforeInvoke出错", e);
            }
        }
    }

    public void afterInvoke(ActionContext context) {
        Objects.requireNonNull(context.getCallee());
        for (ActionInterceptor interceptor : interceptorChain) {
            try {
                interceptor.afterInvoke(context);
            } catch (Exception e) {
                Logger logger = LogManager.getLogger(context.getCallee().getClazzName());
                logger.error("执行afterInvoke出错", e);
            }
        }
    }

    public void onException(ActionContext context) {
        Objects.requireNonNull(context.getCallee());
        for (ActionInterceptor interceptor : interceptorChain) {
            try {
                interceptor.onException(context);
            } catch (Exception e) {
                Logger logger = LogManager.getLogger(context.getCallee().getClazzName());
                logger.error("执行onException出错", e);
            }
        }
    }
}
